package controllers

import (
	"errors"
	"fmt"
	uuid "github.com/iris-contrib/go.uuid"
	jsoniter "github.com/json-iterator/go"
	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/mvc"
	"io/ioutil"
	"net/http"
	"penguin/penguin"
	"penguin/request"
	"penguin/response"
	"penguin/utils"
	"sync"
)

var lock sync.Mutex

type UserController struct {
	Ctx iris.Context
}

func beforeCommonToken(ctx iris.Context) {
	req := response.TokenInfo{}
	err := ctx.ReadJSON(&req)
	if err != nil {
		_, _ = ctx.JSON(response.InvalidParameters)
		return
	}
	user, ok := utils.ValidateToken(&req)
	if !ok {
		ctx.StatusCode(403)
		_, _ = ctx.JSON(response.InvalidParameters)
		return
	}
	ctx.Values().Set("user", user)
	ctx.Next()
}

func (u *UserController) BeforeActivation(b mvc.BeforeActivation) {
	b.Handle("GET", "/debug_login/{nickName:string}", "DebugLogin")
	b.Handle("POST", "/wechat_login", "WechatLogin")
}

// @Title Debug Login
// @Description 虚假登陆
// @Tags user
// @Param nick_name path string true "nick name"
// @Success 200	{object} response.TokenInfo
// @Failure 500 {object} response.JsonResponse "内部错误"
// @router /user/debug_login/{nick_name} [get]
func (u *UserController) DebugLogin(nickName string) response.JsonResponse {
	uuid, err := uuid.NewV4()
	if err != nil {
		u.Ctx.StatusCode(500)
		return response.InternalServerError(err)
	}
	uid := uuid.String()
	token, err := utils.SignToken(uid, nickName, true)
	if err != nil {
		u.Ctx.StatusCode(500)
		return response.InternalServerError(err)
	}
	return response.JsonResponse{
		ErrCode: 0,
		ErrInfo: "",
		Data: response.TokenInfo{
			Token: token,
			Uid:   uid,
		},
	}
}

// @Title Wechat Login
// @Description 微信登陆
// @Tags user
// @Param body body request.WechatLogin true "wechat code"
// @Success 200	{object} response.TokenInfo
// @Failure 500 {object} response.JsonResponse "内部错误"
// @router /user/wechat_login [post]
func (u *UserController) WechatLogin() response.JsonResponse {
	req := request.WechatLogin{}
	err := u.Ctx.ReadJSON(&req)
	fmt.Println(req)
	if err != nil {
		u.Ctx.StatusCode(403)
		return response.JsonResponse{
			ErrCode: 1,
			ErrInfo: "请求无效",
			Data:    "",
		}
	}
	wechatConfig := penguin.GetWechatConfig()
	resp, err := http.Get("https://api.weixin.qq.com/sns/jscode2session?appid=" + wechatConfig.AppId + "&secret=" + wechatConfig.AppSecret + "&js_code=" + req.Code + "&grant_type=authorization_code")
	if err != nil {
		_ = resp.Body.Close()
		penguin.Error(err)
		u.Ctx.StatusCode(500)
		return response.InternalServerError(err)
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		_ = resp.Body.Close()
		penguin.Error(err)
		u.Ctx.StatusCode(500)
		return response.InternalServerError(err)
	}
	_ = resp.Body.Close()
	resCode := response.WechatAuthCode{}
	err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(body, &resCode)
	if err != nil {
		_ = resp.Body.Close()
		penguin.Error(err)
		u.Ctx.StatusCode(500)
		return response.InternalServerError(err)
	}
	if resCode.ErrCode != 0 {
		u.Ctx.StatusCode(500)
		return response.InternalServerError(errors.New(resCode.ErrMsg))
	}
	token, err := utils.SignToken(resCode.OpenId, req.NickName, false)
	if err != nil {
		u.Ctx.StatusCode(500)
		return response.InternalServerError(err)
	}
	return response.JsonResponse{
		ErrCode: 0,
		ErrInfo: "",
		Data: response.TokenInfo{
			Token: token,
			Uid:   resCode.OpenId,
		},
	}
}
